package part2.task3;

import java.util.Stack;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeoutException;

public class ConnectionPool {
    private String url;
    private String user;
    private String password;
    private static final int WAITING_TIMEOUT = 1000;
    private static final int POOL_SIZE = 1000;
    private Stack<ControlledConnection> pool;
    private Semaphore semaphore;
    private ConnectionMonitor monitor;
    public ConnectionPool(String url, String user, String password) {
        this.url = url;
        this.user = user;
        this.password = password;
        semaphore = new Semaphore(POOL_SIZE);
        pool = new Stack<ControlledConnection>();
        monitor=new ConnectionMonitor(this);
        monitor.start();
    }

    public ControlledConnection checkOut() throws TimeoutException{
        if (semaphore.tryAcquire(WAITING_TIMEOUT)) {
            synchronized (pool) {
                ControlledConnection connection;
                if (!pool.isEmpty()) {
                    connection=pool.pop();
                    monitor.addConnection(connection);
                } else {
                    //create new connection
                    connection= new ControlledConnection(null);
                }
                connection.checkOut();
                return connection;
            }
        } else
            throw new TimeoutException();
    }

    public void checkIn(ControlledConnection c) {
        synchronized (pool) {
            pool.push(c);
            monitor.removeConnection(c);
        }
        semaphore.release();
    }
}
